import sun.font.CreatedFontTracker;

import java.util.ArrayList;
import java.util.LinkedList;

public class No059 {
    /**
     * 给定一个数组和滑动窗口的大小，找出所有滑动窗口里数值的最大值。
     * 例如，如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3，
     * 那么一共存在6个滑动窗口，他们的最大值分别为{4,4,6,6,6,5}；
     * 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个：
     * {[2,3,4],2,6,2,5,1}，
     * {2,[3,4,2],6,2,5,1}，
     * {2,3,[4,2,6],2,5,1}，
     * {2,3,4,[2,6,2],5,1}，
     * {2,3,4,2,[6,2,5],1}，
     * {2,3,4,2,6,[2,5,1]}。
     */
    public ArrayList<Integer> maxInWindows(int[] num, int size) {
        ArrayList<Integer> result = new ArrayList<>();
        if (num.length < size || size <= 0) return result;
        // 队列中储存可能是最大值的下标
        LinkedList<Integer> queue = new LinkedList<>();
        for (int i = 0; i < size; i++) {
            while (!queue.isEmpty() && num[i] >= num[queue.getLast()]) {
                queue.removeLast();
            }
            queue.addLast(i);
        }
        for (int i = size; i < num.length; i++) {
            result.add(num[queue.getFirst()]);
            // 新来的更大
            while (!queue.isEmpty() && num[i] >= num[queue.getLast()]) {
                queue.removeLast();
            }
            // 滑出去了
            if (!queue.isEmpty() && queue.getFirst() <= i - size) {
                queue.removeFirst();
            }
            queue.addLast(i);
        }
        result.add(num[queue.getFirst()]);
        return result;
    }
}
